package com.gitee.cnlongdb.server.operator.create;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.gitee.cnlongdb.basic.constant.ConcurrentDataMap;
import com.gitee.cnlongdb.basic.constant.LongDbConstant;
import com.gitee.cnlongdb.basic.entity.database.LongDataBaseEntity;
import com.gitee.cnlongdb.basic.entity.database.LongTableEntity;
import com.gitee.cnlongdb.basic.utils.LongFileOperator;
import com.gitee.cnlongdb.server.connect.LongDbConnect;
import com.gitee.cnlongdb.server.datasync.LongdbMasterSalveDataSync;

/**
 * 系统名称：CreateOperator.java
 * 模块名称：
 * 模块描述：longdb - 创建操作服务实现层
 * 功能列表：
 * 模块作者：ZOUYONG
 * 开发时间：2018年11月11日 上午8:48:56
 * 模块路径：com.gitee.cnlongdb.server.create.CreateOperator
 * 更新记录：
 */
public class CreateOperator {

	private final Logger logger = (Logger) LoggerFactory.getLogger(CreateOperator.class);
	
	// 数据库连接对象
	private LongDbConnect connect;
	public CreateOperator(LongDbConnect connect) {
		logger.debug(LongDbConstant.longdbDefaultName + "初始化[创建执行器]...");
		this.connect = connect;
	}

	/**
	 * 功能描述：创建数据库
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 上午8:48:47
	 * 更新记录：
	 * 返回数据：LongDataBaseEntity
	 */
	public synchronized LongDataBaseEntity createDataBase(String dataBaseName) {
		try {
			String dbPath = connect.getDataBaseRootDirectory() + File.separator + dataBaseName;
			// 创建数据库文件夹
			File dbFile = new File(dbPath);
			if(!dbFile.exists()) {
				dbFile.mkdirs();
			}
			
			// 创建数据库存放表的根目录文件
			File dbHouse = new File(dbPath + File.separator + LongDbConstant.longdbDataBaseHouse);
			if(!dbHouse.exists()) {
				dbHouse.mkdirs();
			}
			
			// 创建表分区的配置文件
			File dbRule = new File(dbPath + File.separator + dataBaseName + LongDbConstant.longdbRuleSuffix);
			if(!dbRule.exists()) {
				dbRule.createNewFile();
			}
			
			// 创建数据库配置文件
			File dbCfg = new File(dbPath + File.separator + dataBaseName + LongDbConstant.longdbCfgSuffix);
			if(!dbCfg.exists()) {
				dbCfg.createNewFile();
				// 写入数据库配置文件
				return writeDataBaseCfgData(dbCfg, connect.getDataBaseRootDirectory(), dataBaseName);
			}
			
			return getLongDataBaseEntity(dataBaseName);
		} catch(Exception e) {
			throw new RuntimeException("创建数据库异常：" + e.getMessage());
		}
	}

	/**
	 * 功能描述：写入数据库配置文件
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月9日 下午2:43:09
	 * 更新记录：
	 * 返回数据：void
	 */
	private LongDataBaseEntity writeDataBaseCfgData(File dbCfg, String dataBaseRootDirectory, String dataBaseName) {
		
		LongDataBaseEntity database = new LongDataBaseEntity();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		database.setDataBaseName(dataBaseName); 							// 数据库名称
		database.setFilePath(
				dbCfg.getParent().replace(dataBaseRootDirectory, ""));	// 数据库路径
		database.setCreateDate(format.format(new Date())); 				// 创建时间
		database.setCreateUser(LongDbConstant.longdbDefaultName);		// 创建人
		database.setEncoding(LongDbConstant.longdbSystemCharset);		// 编码集
		String cfgJsonStr = JSON.toJSONString(database);
		
		LongFileOperator.writeFileByStream(dbCfg, cfgJsonStr);
		ConcurrentDataMap.longDataBaseMap.put(dataBaseName, database);
		
		// 处理主从数据同步
		LongdbMasterSalveDataSync.masterSlaveSyncData(connect, LongDbConstant.longdbActuatorCreate, "createDataBase", dataBaseName);
		return database;
	}

	/**
	 * 功能描述：获取指定数据库的配置信息
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月9日 下午6:29:57
	 * 更新记录：
	 */
	public LongDataBaseEntity getLongDataBaseEntity(String dataBaseName) {
		// 获取数据库的配置信息
		LongDataBaseEntity dataBase = ConcurrentDataMap.longDataBaseMap.get(dataBaseName);
		if(null == dataBase) {
			String dbCfgFilePath = connect.getDataBaseRootDirectory() + File.separator + 
					dataBaseName + File.separator + dataBaseName + LongDbConstant.longdbCfgSuffix;
			File dbCfgFile = new File(dbCfgFilePath);
			if(!dbCfgFile.exists()) {
				return null;
			}
			File dbFile = new File(dbCfgFilePath);
			String jsonStr = LongFileOperator.readFileContentByMappedBuffer(dbFile);
			dataBase = JSON.parseObject(jsonStr, LongDataBaseEntity.class);
		}
		dataBase.setDataBaseRootDirectory(connect.getDataBaseRootDirectory());
		ConcurrentDataMap.longDataBaseMap.put(dataBaseName, dataBase);
		return dataBase;
	}
	
	/**
	 * 功能描述：创建数据表
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 上午8:59:48
	 * 更新记录：
	 * 返回数据：LongDataBaseEntity
	 */
	public LongTableEntity createTable(String tableName) {
		LongTableEntity table = new LongTableEntity();
		table.setTableName(tableName);
		table.setDataBaseName(connect.getDataBaseName());
		table.setDataBaseRootDirectory(connect.getDataBaseRootDirectory());
		return createTable(table);
	}

	/**
	 * 功能描述：创建数据表
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 上午8:51:46
	 * 更新记录：
	 * 返回数据：LongTableEntity
	 */
	public synchronized LongTableEntity createTable(LongTableEntity table) {
		
		String tableName = table.getTableName();
		if(StringUtils.isBlank(tableName)) {
			throw new RuntimeException("创建表的名称不能为空！");
		}
		if(StringUtils.isBlank(table.getDataBaseRootDirectory())) {
			throw new RuntimeException("创建表所在的数据库根目录不能为空！");
		}
		
		try {
			LongDataBaseEntity dataBase = getLongDataBaseEntity(table.getDataBaseName());
			if(null == dataBase) {
				throw new RuntimeException("创建表的数据库不存在！");
			}
			
			String tabPath = table.getDataBaseRootDirectory() + File.separator + 
					table.getDataBaseName() + File.separator + LongDbConstant.longdbDataBaseHouse + File.separator + tableName;
			// 创建表的文件夹
			File tabFile = new File(tabPath);
			if(!tabFile.exists()) {
				tabFile.mkdirs();
			}
			
			// 创建表的配置文件
			String tabCfgPath = tabFile.getAbsolutePath() + File.separator + tableName + LongDbConstant.longdbCfgSuffix;
			File tabCfg = new File(tabCfgPath);
			if(!tabCfg.exists()) {
				tabCfg.createNewFile();
				// 创建表中存储数据的目录文件
				File tableHouse = new File(tabFile.getAbsoluteFile() + File.separator + LongDbConstant.longdbTableDataHouse);
				if(!tableHouse.exists()) {
					tableHouse.mkdirs();
				}
				table.setDataBaseName(table.getDataBaseName());
				table.setFilePath(tabCfg.getParent().replace(table.getDataBaseRootDirectory(), ""));
				// 写入表的配置信息
				String cfgJsonStr = JSON.toJSONString(table);
				LongFileOperator.writeFileByFileWriter(tabCfg, cfgJsonStr);
				ConcurrentDataMap.longdbTableMap.put(tableName, table);
				// 处理主从数据同步
				LongdbMasterSalveDataSync.masterSlaveSyncData(connect, LongDbConstant.longdbActuatorCreate, "createTable", tableName);
			}
		} catch(Exception e) {
			throw new RuntimeException("创建表操作异常：" + e.getMessage());
		}
		return getLongTableByName(tableName);
	}

	/**
	 * 功能描述：获取表的基本信息
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月10日 上午11:54:07
	 * 更新记录：
	 * 返回数据：LongTableEntity
	 */
	public LongTableEntity getLongTableByName(String tableName) {
		if(StringUtils.isBlank(tableName)) {
			return null;
		}
		LongTableEntity table = ConcurrentDataMap.longdbTableMap.get(tableName);
		if(null == table) {
			// 创建表的配置文件
			String tabCfgPath = connect.getDataBaseRootDirectory() + File.separator + connect.getDataBaseName() + File.separator + 
					LongDbConstant.longdbDataBaseHouse + File.separator + tableName + File.separator + tableName + LongDbConstant.longdbCfgSuffix;
			File tabCfgFile = new File(tabCfgPath);
			if(!tabCfgFile.exists()) {
				return null;
			}
			// 获取文件内容
			String jsonStr = LongFileOperator.readFileContentByMappedBuffer(tabCfgFile);
			table = JSON.parseObject(jsonStr, LongTableEntity.class);
			table.setDataBaseRootDirectory(connect.getDataBaseRootDirectory());
			ConcurrentDataMap.longdbTableMap.put(tableName, table);
		}
		return table;
	}

	/**
	 * 功能描述：更新表的配置文件内容
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月24日 上午11:10:25
	 * 更新记录：
	 * 返回数据：void
	 */
	public void updateTableConfigFileContent(LongTableEntity table, boolean isSyncData) {
		if(null == table) {
			throw new RuntimeException("要更新的表数据为空！");
		}
		String tableName = table.getTableName();
		// 创建表的配置文件
		String tabCfgPath = table.getDataBaseRootDirectory() + File.separator + table.getDataBaseName() + File.separator + LongDbConstant.longdbDataBaseHouse + 
				File.separator + tableName + File.separator + tableName + LongDbConstant.longdbCfgSuffix;
		File tabCfgFile = new File(tabCfgPath);
		if(!tabCfgFile.exists()) {
			throw new RuntimeException("表的配置文件不存在！");
		}
		LongFileOperator.writeAvailableTableFileContent(tabCfgFile, JSON.toJSONString(table), true);
		// 处理主从数据同步
		if(isSyncData) {
			LongdbMasterSalveDataSync.masterSlaveSyncData(connect, LongDbConstant.longdbActuatorCreate, "updateTableConfigFileContent", table, false);
		}
	}

}
